package com.imooc.sell.controller;

import com.imooc.sell.VO.xia.CodeVO;
import com.imooc.sell.dao.OrderMasterDao;
import com.imooc.sell.service.AuthoService;
import com.imooc.sell.service.LoginWebSocket;
import com.imooc.sell.service.UserInfoSocket;
import com.imooc.sell.service.impl.AuthoServiceImpl;
import com.imooc.sell.utils.Convertors;
import com.imooc.sell.utils.QRcode.QRCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Controller
@RequestMapping("/autho")
@CrossOrigin
public class AuthoController {

    @Autowired
    private OrderMasterDao orderMasterDao;

    @Autowired
    private LoginWebSocket loginWebsocket;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    AuthoService authoService;

    /**
     * 用于生成带桌号的二维码
     */
    @Test
    public void ssd() {
        AuthoService service = new AuthoServiceImpl();
        CodeVO vo = service.codeGetUrl("snsapi_base", "http://bread.s1.natapp.cc/sell/autho/scanlogin", "5");

        String classPath = null;
        try {
            classPath = ResourceUtils.getURL("classpath").getPath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String baseUrl = classPath.substring(1, classPath.length() - 9);
        try {
            QRCodeUtil.encode(vo.getCodeGetUrl(), "", baseUrl + "target/classes/static/deskNo", true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 买家端通过扫桌面二维码进入界面点餐
     */
    @GetMapping("/scanlogin")
    public ModelAndView scanLogin(@Param("code") String code, @Param("state") String state, Model model) {
        //提示重新扫码界面
        String viewPath = "/login/reScan";
        String deskNo;
        if (!"".equals(state)) {
            deskNo = state.split("#")[0];
            //保存桌号
            model.addAttribute("deskNo", deskNo);
            try {
                /* 获取openid*/
                String openid = authoService.getToken(code).get("openid");
                model.addAttribute("openid", openid);
                viewPath = "/login/index";
            } catch (Exception e) {
                loginWebsocket.sendMessage("0");
                log.error("{}获取openid失败", getClass());
            }
        }
        return new ModelAndView(viewPath);
    }

    /**
     * 后台管理界面用通过扫码方式获得的code获取openid验证用户信息
     *
     * @param code(code码) state(sessionId)
     */
    @GetMapping("/getcode")
    public ModelAndView getCode(@Param("code") String code, @Param("state") String state) {
        String sessionId;
        /*设置默认返回视图*/
        String viewPath = "/login/fail";
        if (!"".equals(state)) {
            /*获取sessionId*/
            sessionId = state.split("#")[0];
            try {
                /* 获取openid*/
                String openid = authoService.getToken(code).get("openid");
                /* 验证是否存在此用户*/
                if (authoService.validate(openid)) {
                    /* 验证通过则 /* 保存sessionId至redis缓存*/
                    redisTemplate.opsForValue().set(openid, sessionId, 7200, TimeUnit.SECONDS);
                    viewPath = "/login/success";
                    /*通知后台管理界面登陆成功,并传回openid*/
                    loginWebsocket.sendMessage(openid);
                    loginWebsocket.onClose();
                }
            } catch (Exception e) {
                loginWebsocket.sendMessage("0");
                log.error("{}获取openid失败", getClass());
            }
        }
        return new ModelAndView(viewPath);
    }

    /**
     * 登出
     */
    @RequestMapping("/admin/logout")
    public ModelAndView logout(@RequestParam String openid) {
        try {
            //删除缓存
            redisTemplate.delete(openid);
        } catch (Exception e) {
            log.error("{}登出失败", getClass());
        }
        return new ModelAndView("redirect:" + "http://bread.s1.natapp.cc/sell/autho/qrcode");
    }

    /**
     * //@param scope 请求方式
     * 得到获取code的url
     */
    @RequestMapping("/code")
    public CodeVO code() {
        //String scope = "snsapi_base";
        String scope = "snsapi_userinfo";
        CodeVO vo = authoService.codeGetUrl(scope, "http://bread.s1.natapp.cc/sell/autho/userinfo", "STATE");
        return vo;
    }


    /**
     * 通过wx服务器获取用户openid
     */
    @RequestMapping("/openid")
    public ModelAndView openid(@RequestParam String code, Model model) {
        Map<String, String> m = null;
        Map<String, Object> map = new HashMap<>();
        //设置默认openid
        model.addAttribute("openid", "");
        //设置默认桌号
        model.addAttribute("deskNo", "-1");
        if (!"".equals(code) && null != code) {
            m = authoService.getToken(code);
        } else
            log.error("{}: openid()code为空" + getClass());
        if (m != null && 3 == m.size()) {
            map.putAll(m);
            map.put("mcode", 1);
            map.put("msg", "获取openid成功");
            model.addAttribute("openid", map.get("openid"));
        } else {
            map.put("mcode", 0);
            map.put("msg", "获取openid失败");
        }
        return new ModelAndView("/login/index");
    }


    /**
     * 辅助函数 获取access_token和openid
     */
    private Map<String, String> getToken(String code) {
        Map<String, String> m = new HashMap<>();
        if (!"".equals(code) && null != code) {
            m = authoService.getToken(code);
        } else {
            log.error("code为空");
        }
        return m;
    }

    /**
     * 拉取用户信息
     *
     * @author wxt.xia
     */
    @RequestMapping("/userinfo")
    //@ResponseBody
    public ModelAndView getUserInfo(@RequestParam String code, Model model) {
        model.addAttribute("mcode", 0);
        model.addAttribute("openid", "");
        model.addAttribute("headImg", "");
        /* 先获取accessToken和openid*/
        Map<String, String> m = getToken(code);

        /* 初始化返回列表*/
        Map<String, Object> map = new HashMap<>();
        /*是否获取到token和openid*/
        if (3 == m.size()) {
            map = authoService.getUserInfo(m.get("openid"), m.get("access_token"), m.get("refresh_token"));
            model.addAttribute("mcode", map.get("mcode"));
            model.addAttribute("openid", map.get("openid"));
            model.addAttribute("headImg", map.get("headImg"));
            model.addAttribute("nickName", map.get("nickName"));
            model.addAttribute("deskNo", orderMasterDao.findAllByBuyerOpenidAndBuyerPhoneIsNotNullOrderByCreateTimeDesc
                    ((String) map.get("openid")).get(0).getBuyerAdderss());
        } else {
            model.addAttribute("mcode", 0);
        }
        return new ModelAndView("/order/remarkOrderList");
    }

    /**
     * 获取用户sessionID生成二维码,返回二维码链接
     */
    @RequestMapping("/qrcode")
    public ModelAndView qrCode(HttpSession session, Model model) {
        /* 获取当前线程Id*/
        String sessionId = session.getId();
        /* 生成获取code的连接*/
        CodeVO vo = authoService.codeGetUrl("snsapi_base", "http://bread.s1.natapp.cc/sell/autho/getcode", sessionId);
        /* 生成二维码*/
        String url;
        String baseUrl;
        try {
            /* *获取图片路径*/
            String classPath = ResourceUtils.getURL("classpath").getPath();
            baseUrl = classPath.substring(1, classPath.length() - 9);
            try {
                url = QRCodeUtil.encode(vo.getCodeGetUrl(), "", baseUrl + "target/classes/static/qrcode", true);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("生成二维码失败");
                model.addAttribute("msg", "请重新点击");
                return new ModelAndView("/login/login");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            e.printStackTrace();
            log.error("生成二维码失败");
            model.addAttribute("msg", "请重新点击");
            return new ModelAndView("/login/login");
        }

        model.addAttribute("qrUrl", url);
        return new ModelAndView("/login/qrLogin");
    }

    /**
     * 返回登陆界面
     */
    @RequestMapping("/login")
    public ModelAndView login(Model model) {
        return new ModelAndView("/autho/qrcode");
    }

    @RequestMapping("/")
    public ModelAndView hello() {
        return new ModelAndView("/login/hello");
    }


}
